//
//  DoorLockUtil+Cache.swift
//  ZhiTing
//
//  Created by iMac on 2022/5/10.
//

import Foundation
import RealmSwift

extension DoorLockUtil {
    
    /// 获取对应家庭的私有设备
    /// - Parameter area_id: 家庭id
    /// - Returns: 私有设备
    static func getDoorLocks(area_id: String?) -> [DoorLock] {
        guard let area_id = area_id else {
            return []
        }
        let realm = try! Realm()
        return realm
            .objects(DoorLockCache.self).filter("area_id = '\(area_id)'")
            .map { cache -> DoorLock in
                let d = DoorLock()
                d.uuid = cache.uuid
                d.name =  cache.name
                d.plugin_id = cache.plugin_id
                d.model = cache.model
                d.area_id = cache.area_id
                d.mac_addr = cache.mac_addr
                d.pin = cache.pin
                d.needEncode = cache.needEncode
                return d
            }
        
    }
    
    /// 缓存门锁
    /// - Parameter doorLock: 门锁
    func cacheDoorLock(doorLock: DoorLock) {
        guard doorLock.uuid.count > 0 else { return }
        let realm = try! Realm()
        if let cache = realm.objects(DoorLockCache.self).filter("uuid = '\(doorLock.uuid)'").first {
            try? realm.write {
                cache.area_id = doorLock.area_id
                cache.name = doorLock.name
                cache.model = doorLock.model
                cache.plugin_id = doorLock.plugin_id
                cache.mac_addr = doorLock.mac_addr
                cache.pin = doorLock.pin
                cache.needEncode = doorLock.needEncode
            }
        } else {
            let cache = DoorLockCache()
            cache.area_id = doorLock.area_id
            cache.uuid = doorLock.uuid
            cache.name = doorLock.name
            cache.model = doorLock.model
            cache.plugin_id = doorLock.plugin_id
            cache.mac_addr = doorLock.mac_addr
            cache.pin = doorLock.pin
            cache.needEncode = doorLock.needEncode
            try? realm.write {
                realm.add(cache)
            }
        }
    }
    
    func getDoorLock(uuid: String) -> DoorLock? {
        let realm = try! Realm()
        if let cache = realm.objects(DoorLockCache.self).filter("uuid = '\(uuid)'").first {
            let d = DoorLock()
            d.name = cache.name
            d.pin = cache.pin
            d.model = cache.model
            d.mac_addr = cache.mac_addr
            d.needEncode = cache.needEncode
            d.uuid = cache.uuid
            d.plugin_id = cache.plugin_id
            d.area_id = cache.area_id
            return d
        }
        return nil
    }
    
    /// 删除门锁
    /// - Parameter lock_id: 锁uuid
    static func deleteDoorLock(lock_id: String) {
        let realm = try! Realm()
        let cache = realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'")
        let users = realm.objects(DoorLockUserCache.self).filter("lock_id = '\(lock_id)'")
        let verifications = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)'")
        let logs = realm.objects(DoorLockLogCache.self).filter("lock_id = '\(lock_id)'")
        
        try? realm.write {
            realm.delete(cache)
            realm.delete(users)
            realm.delete(verifications)
            realm.delete(logs)
        }
    }
    
    /// 删除门锁
    /// - Parameter lock_id: 锁uuid
    static func deleteDoorLock(area_id: String?) {
        guard let area_id = area_id else {
            return
        }

        let realm = try! Realm()
        if let cache = realm.objects(DoorLockCache.self).filter("area_id = '\(area_id)'").first {
            let users = realm.objects(DoorLockUserCache.self).filter("lock_id = '\(cache.uuid)'")
            let verifications = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(cache.uuid)'")
            let logs = realm.objects(DoorLockLogCache.self).filter("lock_id = '\(cache.uuid)'")
            
            try? realm.write {
                realm.delete(cache)
                realm.delete(users)
                realm.delete(verifications)
                realm.delete(logs)
            }
        }
    }
    
    /// 删除门锁
    /// - Parameter lock_id: 锁uuid
    /// - Parameter name: 名称
    static func editDoorLock(lock_id: String, name: String) {
        let realm = try! Realm()
        if let cache = realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").first {
            try? realm.write {
                cache.name = name
            }
        }
        
        
        
    }
    
    /// 添加用户
    /// - Parameters:
    ///   - lock_id: 门锁uuid
    ///   - username: 用户名称
    ///   - role_type: 用户类型
    /// - Returns: 返回结果json
    func addUser(lock_id: String, username: String, role_type: Int) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        
        guard [1, 2, 3, 4, 6].contains(role_type ) else {
            return "{\"status\": -1,\"error\": \"用户类型不存在\"}"
        }
        
        let currentMaxId = realm.objects(DoorLockUserCache.self).filter("lock_id = '\(lock_id)'").sorted(byKeyPath: "id", ascending: true).last?.id ?? 0
        let id = currentMaxId + 1
        
        let cache = DoorLockUserCache()
        cache.lock_id = lock_id
        cache.id = id
        cache.name = username
        cache.role_type = role_type
        try? realm.write {
            realm.add(cache)
        }
        
        return "{\"status\": 0,\"error\": \"\",\"data\":{\"id\":\(id)}}"
    }
    
    /// 编辑用户
    /// - Parameters:
    ///   - lock_id: 锁id
    ///   - user_id: 用户id
    ///   - name: 名称
    func editUser(lock_id: String, user_id: Int, name: String) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        guard let user = realm.objects(DoorLockUserCache.self).filter("lock_id = '\(lock_id)' AND id = \(user_id)").first else {
            return "{\"status\": -1,\"error\": \"用户不存在\"}"
        }
        
        try? realm.write {
            user.name = name
        }
        
        return "{\"status\": 0,\"error\": \"\"}"
    }
    
    /// 删除用户
    /// - Parameters:
    ///   - lock_id: 锁id
    ///   - user_id: 用户id
    func deleteUser(lock_id: String, user_id: Int) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        guard let user = realm.objects(DoorLockUserCache.self).filter("lock_id = '\(lock_id)' AND id = \(user_id)").first else {
            return "{\"status\": -1,\"error\": \"用户不存在\"}"
        }
        
        let verifications = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)' AND user_id = \(user_id)")
        
        try? realm.write {
            verifications.forEach { v in
                v.user_id = nil
            }
            realm.delete(user)
        }
        
        return "{\"status\": 0,\"error\": \"\"}"
    }
    
    
    /// 用户详情
    /// - Parameters:
    ///   - lock_id: 锁uuid
    ///   - user_id: 用户id
    func userDetail(lock_id: String, user_id: Int) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        
        guard let user = realm.objects(DoorLockUserCache.self).filter("lock_id = '\(lock_id)' AND id = \(user_id)").first else {
            return "{\"status\": -1,\"error\": \"用户不存在\"}"
        }
        
        let verifications = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)' AND user_id = \(user.id)")
        let verifications_json = verifications
            .map { val -> String in
                return "{\"number_id\": \(val.number_id), \"password\": \"\(val.password ?? "")\", \"number_type\": \(val.number_type), \"number_name\": \"\(val.number_name)\", \"role_type\": \(val.role_type), \"valid_time\": \"\(val.valid_time ?? "")\"}"
            }
            .joined(separator: ",")
        let user_json = "{\"name\": \"\(user.name)\", \"role_type\": \(user.role_type), \"id\": \(user.id), \"verifications\": [\(verifications_json)]}"
        
        return "{\"status\": 0,\"error\": \"\", \"data\": \(user_json)}"
        
        
    }
    
    /// 用户列表
    /// - Parameters:
    ///   - lock_id: 门锁uuid
    func userList(lock_id: String) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        
        let users = realm.objects(DoorLockUserCache.self).filter("lock_id = '\(lock_id)'")
        let user_json = users
            .map { user -> String in
                let verifications = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)' AND user_id = \(user.id)")
                let verifications_json = verifications
                    .map { val -> String in
                        return "{\"number_id\": \(val.number_id), \"password\": \"\(val.password ?? "")\", \"number_type\": \(val.number_type), \"number_name\": \"\(val.number_name)\", \"role_type\": \(val.role_type), \"valid_time\": \"\(val.valid_time ?? "")\"}"
                    }
                    .joined(separator: ",")
                return "{\"name\": \"\(user.name)\", \"role_type\": \(user.role_type), \"id\": \(user.id), \"verifications\": [\(verifications_json)]}"
            }
            .joined(separator: ",")
        
        return "{\"status\": 0,\"error\": \"\", \"data\": {\"users\": [\(user_json)]}}"
    }
    
    /// 验证方式列表
    /// - Parameters:
    ///   - lock_id: 锁uuid
    ///   - number_type: 验证方式类型
    ///   - bind: 是否已绑定
    func verificationList(lock_id: String, number_type: Int?, role_type: Int?, bind: Bool?) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        
        
        var verifications = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)'")
        if let number_type = number_type {
            verifications = verifications.filter("number_type = \(number_type)")
            
        }
        
        if let bind = bind {
            if bind {
                verifications = verifications.filter("user_id != nil")
            } else {
                verifications = verifications.filter("user_id = nil")
            }
            
            
        }
        
        if let role_type = role_type {
            verifications = verifications.filter("role_type = \(role_type)")
        } else {
            verifications = verifications.filter("role_type = 6 OR role_type = 1 OR role_type = 3 OR role_type = 4")
            
        }
        
        
        
        let verifications_json = verifications
            .map { val -> String in
                return "{\"number_id\": \(val.number_id), \"password\": \"\(val.password ?? "")\", \"number_type\": \(val.number_type), \"number_name\": \"\(val.number_name)\", \"role_type\": \(val.role_type), \"valid_time\": \"\(val.valid_time ?? "")\", \"create_time\": \(val.create_time ?? 0)}"
            }
            .joined(separator: ",")
        
        
        return "{\"status\": 0,\"error\": \"\", \"data\": {\"verifications\": [\(verifications_json)]}}"
    }
    
    /// 缓存从锁上读到的验证方式
    func cacheVerifcation(lock_id: String, number_type: Int, number_id: Int) {
        let realm = try! Realm()
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return
        }
        let v = DoorLockVerificationCache()
        v.number_id = number_id
        v.create_time = Int(Date().timeIntervalSince1970)
        v.number_type = number_type
        v.lock_id = lock_id
        if number_type == 1 { /// 密码
            v.number_name = "密码 \(number_id)"
            if 0...4 ~= number_id {
                v.role_type = 6
            } else if 5...79 ~= number_id {
                v.role_type = 1
            } else if 80...84 ~= number_id {
                v.role_type = 2
            } else if 85...89 ~= number_id {
                v.role_type = 4
            } else if 90...99 ~= number_id {
                v.role_type = 3
            }
        } else if number_type == 2 { /// 指纹
            v.number_name = "指纹 \(number_id)"
            if 0...9 ~= number_id {
                v.role_type = 6
            } else if 10...84 ~= number_id {
                v.role_type = 1
            } else if 85...89 ~= number_id {
                v.role_type = 4
            } else if 90...99 ~= number_id {
                v.role_type = 3
            }
        } else if number_type == 6 { /// 卡片
            v.number_name = "卡片 \(number_id)"
            if 0...84 ~= number_id {
                v.role_type = 1
            } else if 85...89 ~= number_id {
                v.role_type = 4
            } else if 90...99 ~= number_id {
                v.role_type = 3
            }
        }
        let exists = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)'")
        if !exists.contains(where: { $0.number_id == v.number_id && $0.number_type == v.number_type }) {
            try? realm.write {
                realm.add(v)
            }
        }
        
    }
    
    /// 缓存从锁上读到的验证方式
    func cacheVerifcations(lock_id: String, number_type: Int, number_id: [Int]) {
        let realm = try! Realm()
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return
        }
        
        let verifications = number_id
            .map { number_id -> DoorLockVerificationCache in
                let v = DoorLockVerificationCache()
                v.number_id = number_id
                v.number_type = number_type
                v.lock_id = lock_id
                if number_type == 1 { /// 密码
                    v.number_name = "密码 \(number_id)"
                    if 0...4 ~= number_id {
                        v.role_type = 6
                    } else if 5...79 ~= number_id {
                        v.role_type = 1
                    } else if 80...84 ~= number_id {
                        v.role_type = 2
                    } else if 85...89 ~= number_id {
                        v.role_type = 4
                    } else if 90...99 ~= number_id {
                        v.role_type = 3
                    }
                } else if number_type == 2 { /// 指纹
                    v.number_name = "指纹 \(number_id)"
                    if 0...9 ~= number_id {
                        v.role_type = 6
                    } else if 10...84 ~= number_id {
                        v.role_type = 1
                    } else if 85...89 ~= number_id {
                        v.role_type = 4
                    } else if 90...99 ~= number_id {
                        v.role_type = 3
                    }
                } else if number_type == 6 { /// 卡片
                    v.number_name = "卡片 \(number_id)"
                    if 0...84 ~= number_id {
                        v.role_type = 1
                    } else if 85...89 ~= number_id {
                        v.role_type = 4
                    } else if 90...99 ~= number_id {
                        v.role_type = 3
                    }
                }
                return v
            }
        
        let exists = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)'")
        let notExists = realm.objects(DoorLockVerificationCache.self)
            .filter("lock_id = '\(lock_id)'")
            .filter { cache in
                !number_id.contains(cache.number_id) && cache.number_type == number_type
            }

        try? realm.write {
            realm.delete(notExists)
            verifications.forEach { v in
                if !exists.contains(where: { $0.number_id == v.number_id && $0.number_type == v.number_type }) {
                    realm.add(v)
                }
            }
        }
    }
    
    /// 添加验证方式
    /// - Parameters:
    ///   - lock_id: 门锁uuid
    ///   - number_id: 门锁本地编号
    ///   - number_type: 验证方式类型
    ///   - number_name: 名称
    ///   - password: 密码
    ///   - valid_time: 时段信息
    ///   - create_time: 创建时间
    ///   - role_type: 用户类型     Normal = 1 //普通用户 OneTime = 2 //一次性 Guest = 3 //常访客 Coerce = 4 //胁迫
    func addVerification
    (
        lock_id: String,
        password: String? = nil,
        number_id: Int,
        number_type: Int,
        number_name: String,
        valid_time: String?,
        create_time: Int? = Int(Date().timeIntervalSince1970),
        role_type: Int
    ) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        
        let cache = DoorLockVerificationCache()
        cache.lock_id = lock_id
        if role_type == 2 {
            cache.password = password
        }
        cache.number_id = number_id
        cache.number_type = number_type
        cache.number_name = number_name
        cache.valid_time = valid_time
        cache.role_type = role_type
        cache.create_time = create_time
        try? realm.write {
            realm.add(cache)
        }
        
        return "{\"status\": 0,\"error\": \"\",\"data\":{\"number_id\":\(number_id)}}"
    }
    
    /// 编辑用户
    /// - Parameters:
    ///   - lock_id: 锁id
    ///   - number_type: 验证方式类型
    ///   - number_id: 门锁本地编号
    ///   - name: 名称
    func editVerification(lock_id: String, number_type: Int, number_id: Int, name: String) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        guard let verification = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)' AND number_id = \(number_id) AND number_type = \(number_type)").first else {
            return "{\"status\": -1,\"error\": \"验证方式不存在\"}"
        }
        
        try? realm.write {
            verification.number_name = name
        }
        
        return "{\"status\": 0,\"error\": \"\"}"
    }
    
    /// 删除验证方式
    /// - Parameters:
    ///   - lock_id: 门锁uuid
    ///   - number_type: 验证方式类型
    ///   - number_id: 门锁本地编号
    func deleteVerification(lock_id: String, number_type: Int, number_id: Int) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        
        let caches = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)' AND number_type = \(number_type) AND number_id = \(number_id)")
        try? realm.write {
            realm.delete(caches)
        }
        
        
        return "{\"status\": 0,\"error\": \"\"}"
    }
    
    /// 解绑验证方式
    /// - Parameters:
    ///   - lock_id: 门锁uuid
    ///   - number_type: 验证方式类型
    ///   - number_id: 门锁本地编号
    func unbindVerification(lock_id: String, number_type: Int, number_id: Int) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        
        let caches = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)' AND number_type = \(number_type) AND number_id = \(number_id)")
        try? realm.write {
            caches.forEach { $0.user_id = nil }
        }
        
        
        return "{\"status\": 0,\"error\": \"\"}"
    }
    
    /// 按区段删除验证方式
    func rangeDeleteVerification(lock_id: String, number_type: Int, start: Int, end: Int) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        
        let caches = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)' AND number_type = \(number_type) AND number_id >= \(start) AND number_id <= \(end)")
        try? realm.write {
            realm.delete(caches)
        }
        
        
        return "{\"status\": 0,\"error\": \"\"}"
    }
    
    /// 绑定验证方式
    /// - Parameters:
    ///   - lock_id: 门锁uuid
    ///   - user_id: 用户id
    ///   - verifications: (number_id: 门锁本地编号 number_type: 验证方式)
    func bindValidation(lock_id: String, user_id: Int, verifications: [(number_id: Int, number_type: Int)]) -> String {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"门锁不存在\"}"
        }
        
        guard realm.objects(DoorLockUserCache.self).filter("id = \(user_id) AND lock_id = '\(lock_id)'").count > 0 else {
            return "{\"status\": -1,\"error\": \"用户不存在\"}"
        }
        
        
        
        try? realm.write {
            verifications.forEach { v in
                if let validation = realm.objects(DoorLockVerificationCache.self).filter("number_type = \(v.number_type) AND number_id = \(v.number_id) AND lock_id = '\(lock_id)'").first {
                    validation.user_id = user_id
                }
            }
        }
        
        
        return "{\"status\": 0,\"error\": \"\"}"
    }
    
    /// 缓存日志
    /// - Parameter log: 日志
    func cacheLog(log: DoorLockLogCache) {
        let realm = try! Realm()
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(log.lock_id)'").count > 0 else { return }
        
        let currentMaxId = realm.objects(DoorLockLogCache.self).filter("lock_id = '\(log.lock_id)'").sorted(byKeyPath: "id", ascending: true).last?.id ?? 0
        log.id = currentMaxId + 1
        try? realm.write {
            realm.add(log)
        }
    }
    
    /// 日志列表
    /// - Parameters:
    ///   - event_type: 事件类型
    ///   - lock_id: 锁uuid
    ///   - start_at: 开始时间戳
    ///   - end_at: 结束时间戳
    ///   - size: 分页大小
    ///   - index: 最大的一条日志id
    /// - Returns: 日志列表json
    func logList(lock_id: String,
                 event_type: [Int],
                 start_at: Int?,
                 end_at: Int?,
                 size: Int?,
                 index: Int?)
    -> String {
        let realm = try! Realm()
        var filter = "lock_id = '\(lock_id)'"
        if event_type.count > 0 {
            filter = filter + " AND " + event_type
                .map { "event_type = \($0)" }
                .joined(separator: " OR ")
        }
        
        var logCaches = realm.objects(DoorLockLogCache.self).filter(filter).sorted(byKeyPath: "time", ascending: false)
        
        if let start_at = start_at, let end_at = end_at {
            logCaches = logCaches.filter("time >= \(start_at) AND time < \(end_at)")
        }
        
        if let index = index, index != -1 {
            logCaches = logCaches.filter("time < \(index)")
        }
        
        
        let logsJson = logCaches
            .map { cache -> String in
                var params = [String]()
                params.append("\"id\": \(cache.id)")
                params.append("\"event_type\": \(cache.event_type)")
                params.append("\"time\": \(cache.time)")
                if let number_type = cache.number_type {
                    params.append("\"number_type\": \(number_type)")
                }
                if let number_id = cache.number_id {
                    params.append("\"number_id\": \(number_id)")
                }
                
                if let number_type = cache.number_type,
                   let number_id = cache.number_id,
                   let user_id = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)' AND number_id = \(number_id) AND number_type = \(number_type)").first?.user_id,
                   let username = realm.objects(DoorLockUserCache.self.self).filter("lock_id = '\(lock_id)' AND id = \(user_id)").first?.name {
                    params.append("\"username\": \"\(username)\"")
                }
                return "{" + params.joined(separator: ",") + "}"
            }
            .prefix(size ?? logCaches.count)
            .joined(separator: ",")
        
        return "{\"status\": 0,\"error\": \"\", \"data\": {\"logs\": [\(logsJson)]}}"
    }
    
    
    /// 获取需要同步到SA上的数据
    /// - Parameter lock_id: 锁id
    /// - Returns: data
    static func getUploadData(lock_id: String) -> [String: Any]? {
        let realm = try! Realm()
        
        guard realm.objects(DoorLockCache.self).filter("uuid = '\(lock_id)'").count > 0 else {
            return nil
        }
        
        let users = realm.objects(DoorLockUserCache.self).filter("lock_id = '\(lock_id)'")
        let user_json = users
            .map { user -> String in
                let verifications = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)' AND user_id = \(user.id)")
                let verifications_json = verifications
                    .map { val -> String in
                        return "{\"number_id\": \(val.number_id), \"password\": \"\(val.password ?? "")\", \"number_type\": \(val.number_type), \"number_name\": \"\(val.number_name)\", \"role_type\": \(val.role_type), \"valid_time\": \"\(val.valid_time ?? "")\"}"
                    }
                    .joined(separator: ",")
                return "{\"name\": \"\(user.name)\", \"role_type\": \(user.role_type), \"id\": \(user.id), \"verifications\": [\(verifications_json)]}"
            }
            .joined(separator: ",")
        
        
        let logs_json = realm
            .objects(DoorLockLogCache.self)
            .filter("lock_id = '\(lock_id)'")
            .sorted(byKeyPath: "time", ascending: false)
            .map { cache -> String in
                var params = [String]()
                params.append("\"id\": \(cache.id)")
                params.append("\"event_type\": \(cache.event_type)")
                params.append("\"time\": \(cache.time)")
                if let number_type = cache.number_type {
                    params.append("\"number_type\": \(number_type)")
                }
                if let number_id = cache.number_id {
                    params.append("\"number_id\": \(number_id)")
                }
                
                if let number_type = cache.number_type,
                   let number_id = cache.number_id,
                   let user_id = realm.objects(DoorLockVerificationCache.self).filter("lock_id = '\(lock_id)' AND number_id = \(number_id) AND number_type = \(number_type)").first?.user_id {
                    params.append("\"user_id\": \"\(user_id)\"")
                }
                return "{" + params.joined(separator: ",") + "}"
            }
            .joined(separator: ",")
        
        
        guard
            let jsonData =  "{\"users\": [\(user_json)], \"logs\": [\(logs_json)]}".data(using: .utf8),
            let dict = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any]
        else {
            return nil
        }
        
        return dict
        
    }
}
